<template>
  <div>
    <van-cell title="新增" icon="plus" @click="onCreate" />
    <div>
      <div v-for="(val, index) in value_new2" :key="`new_${index}`">
        <ListCell
          :data="val"
          :config="config"
          is-link
          @myclick="
            res => {
              onClickO2m({ op: 'new-edit', index, value: val, config })
            }
          "
        />
      </div>
    </div>

    <div>
      <div v-for="(val, index) in value_old" :key="`old_${index}`">
        <ListCell
          :data="val"
          :config="config"
          is-link
          @myclick="
            res => {
              onClickO2m({ op: 'old-edit', index, value: val, config })
            }
          "
        />
      </div>
    </div>

    <ViewPopup
      v-model="o2mValue"
      :show.sync="o2mPopupShow"
      :config="config"
      :data="o2mData"
      :index="o2mIndex"
      :op="o2mOp"
      :options="o2mOptions"
      @submit="onSubmit"
      @showclose="
        () => {
          o2mPopupShow = false
        }
      "
    />
  </div>
</template>

<script>
import ListCell from '@/components/ListPage/ListCell'
import ViewPopup from './o2mPopup'

export default {
  name: 'ViewO2m',
  components: { ListCell, ViewPopup },

  props: {
    value: { type: Array, default: () => [] },
    data: { type: Array, default: () => [] },
    config: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },

  data() {
    return {
      o2mValue: {},

      o2mPopupShow: false,

      o2mData: {},
      o2mIndex: -1,
      o2mOp: null,
      o2mOptions: {}
    }
  },
  computed: {
    value2: {
      get() {
        // console.log('value2', this.value)
        return this.value.map((item, index) => {
          const [op, rid, val] = item
          if (op === 0) {
            return [op, rid, { ...val, _index: index }]
          } else {
            return item
          }
        })
      },
      set(values) {
        const values2 = values.map(item => {
          const [op, rid, val] = item
          if (op === 0) {
            delete val._index
            return [op, rid, { ...val }]
          } else if (op === 1) {
            const val2 = { ...val }
            delete val2.id
            return [1, rid, val2]
          } else {
            return item
          }
        })
        this.$emit('input', values2)
      }
    },

    value_new: {
      get() {
        const value2_new = this.value2.filter(item => item[0] === 0)
        return value2_new.map(item => item[2])
      },
      set(val) {
        const value2_new_not = this.value2.filter(item => item[0] !== 0)
        const val_new = val.map(item => [0, 0, item])
        const ret = [...val_new, ...value2_new_not]
        this.value2 = ret
      }
    },

    value_new2() {
      // console.log('value_new2', this.value2, this.value_new)
      return this.value_new.map(item => this.formatValues(item))
    },

    value_old() {
      // 原有部分
      // data 中 过滤掉 this.value2 中 已经删除的
      // 再 从 this.value2 找 被编辑的, 用 被编辑后的属性值

      const value2_write = this.value2.filter(item => item[0] === 1)

      const value2_unlink_ids = this.value2
        .filter(item => item[0] === 2)
        .map(item => item[1])

      // console.log('value3,this.config, ', this.config.fields, this.config)

      const from_old = this.data
        .filter(item => !value2_unlink_ids.includes(item.id))
        .map(item => {
          // 被编辑后  需要处理  m2o__name 的值
          const wrs = value2_write.filter(it => it[1] === item.id)

          const wr = wrs.length ? wrs[0][2] : {}
          const wr2 = this.formatValues(wr)

          return { ...item, ...wr2 }
        })
      return from_old
    },

    value_old2() {
      //
      return this.value_old
    }
  },
  async created() {
    //
  },

  async mounted() {
    // console.log('FormO2m, config,', this.config.name, this.config)
    // console.log('FormO2m, value,', this.value)
    // console.log('FormO2m, data,', this.data)

    const config = this.config

    const fields = (config.propForView || {}).fields || {}

    const metadata = config.fields || {}
    const fs = Object.keys(fields).reduce((acc, cur) => {
      const meta = metadata[cur] || {}
      if (['many2one', 'selection'].includes(meta.type)) {
        acc[cur] = { fields: meta.fields }
      } else if (['many2many'].includes(meta.type)) {
        if (metadata[cur].selected) {
          acc[cur] = { fields: meta.fields }
        }
      }
      return acc
    }, {})

    const refModel = this.config.Model.env(this.config.relation)

    let options = {}
    if (Object.keys(fs).length) {
      options = await refModel.get_options(fs)
    }

    this.o2mOptions = options
    // console.log('onClickO2m,options,', options)
  },

  methods: {
    //

    formatValues(item) {
      //
      const metadata = this.config.fields
      const options = this.o2mOptions

      return Object.keys(item).reduce((acc, cur) => {
        const meta = metadata[cur] || {}
        acc[cur] = item[cur]
        if (['selection', 'many2one'].includes(meta.type)) {
          const ops = options[cur] || []
          const ops2 = ops.filter(op => op.value === item[cur])
          const op = ops2.length ? ops2[0] : {}
          acc[`${cur}__name`] = op.text
        }
        return acc
      }, {})
    },

    onCreate() {
      this.onClickO2m({
        op: 'new-new',
        index: -1,
        value: {},
        config: this.config
      })
    },

    onSubmit({ op, index, value }) {
      // console.log('onSubmit 1:', op, index, value)

      if (op === 'new-new') {
        const vals = [...this.value_new, value]
        this.value_new = vals
      } else if (op === 'new-edit') {
        const vals = [...this.value2]
        vals[value._index] = [0, 0, value]
        this.value2 = vals
      } else if (op === 'new-edit-del') {
        const vals = [...this.value2]
        vals.splice(value._index, 1)
        this.value2 = vals
      } else if (op === 'old-edit') {
        const vals = [...this.value2]
        const index1 = vals.findIndex(
          item => item[0] === 1 && item[1] === value.id
        )
        if (index1 >= 0) {
          vals[index1] = [1, value.id, value]
        } else {
          vals.push([1, value.id, value])
        }
        this.value2 = vals
      } else if (op === 'old-edit-del') {
        const vals = [...this.value2]
        const index1 = vals.findIndex(
          item => item[0] === 1 && item[1] === value.id
        )
        if (index1 >= 0) {
          vals.splice(index1, 1)
        }
        vals.push([2, value.id, {}])
        this.value2 = vals
      }

      // list 列表 做两份
      // 第一份 为 新增部分， 第二份为 原有部分

      // 对于新部分
      // 点击新增 按钮, 打开 popup form , 标记为 新增操作
      // 回来后, 在 this.value2 中 new 一条

      // 点击编辑按钮, 打开 popup form , 标记为 new-edit 操作
      // 此时 index 为 this.value2 中的 位置
      // 回来后, 若为编辑 则 更新 this.value2 [ index ]
      // 回来后, 若为删除 则 del this.value2 [ index ], 同时 this.value2 的 index 刷新了

      // 对于旧的部分
      // 点击编辑按钮, 打开 popup form , 标记为 old-edit 操作
      // 此时 有 id,
      //  若为 编辑返回,  this.value2 中 查找, 找到则更新, 找不到则 加一条
      //  若为 删除返回,  this.value2 中 查找, 找到 则  删除之; 找不到 则没关系;
      //     之后 在 this.value2 中 添加一条 删除操作

      // if()
      this.o2mPopupShow = false
    },

    async onClickO2m({ op, index, value, config }) {
      //
      // console.log('onClickO2m,', op, index, value, config)

      this.o2mData = { ...value }
      this.o2mValue = Object.keys(value).reduce((acc, cur) => {
        if (cur.split('__').length === 1) {
          if (cur !== 'display_name') {
            acc[cur] = value[cur]
          }
        }

        return acc
      }, {})
      this.o2mIndex = index
      this.o2mOp = op
      this.o2mPopupShow = true
      // console.log('onClickO2m, o2mValue,', this.o2mValue)
    }
  }
}
</script>

<style type="text/css"></style>
